#!/usr/bin/python
#Copyright 2006 Jacques Richer
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#Imports from standard library
import os, re
from urllib import quote_plus, unquote_plus
from types import *

#Imports from external modules 
import cherrypy
from pysqlite2 import dbapi2 as sqlite

#Imports from my modules
from SafeHtml import *
from dbutils import *

def xfhelper(matchobj):
	x = matchobj.group(1)
	return """<a href="/showpage/%s">%s</a>""" % (quote_plus(x), x)

def ref_transform(s):
	if s == None:
		return s
	rex="""\[([0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@\\^_`{|}~ ]+)\]"""
	x = re.sub(rex, xfhelper, s)
	return x

class WSRoot:
	def index(self):
		x = '/showpage/%s' % (quote_plus(upw_config['start_page']))
		raise cherrypy.HTTPRedirect(x)
	index.exposed=True


	def addnew(self, title=None, content=None):
		id = None
		if title != None:
			title=onlySafe(title)
		else:
			title='New Page'
		if content == None:
			x = upw_pages[title]
			if x:
				(content, id) = x
		if content == None:
			content = 'Type page text here.'
		content=cleanString(content)
		repl = {'<<TITLE>>': title,'<<QTITLE>>':quote_plus(title) ,"<<PAGETEXT>>": content}
		if id:
			repl['<<ID>>']=id
		else:
			repl['<<ID>>']='New'
		pgparts= ['edit_head', 'edit_body_prefix', 'edit_body', 'body_postfix', 'html_close']
		return buildpage(pgparts, repl)
	addnew.exposed = True
	
	def editpage(self, *args):
		if not args:
			raise cherrypy.HTTPRedirect('/addnew')
		title=unquote_plus(args[0])
		title=onlySafe(title)
		if len(args) > 1:
			content=cleanString(args[1])
		else:
			content=None
		return self.addnew(title=title, content=content)
	editpage.exposed = True

	def postpage(self, pagename, pagetext, revnote=""):
		pagetext = cleanString(pagetext)
		pagename = onlySafe(pagename)
		revnote = cleanString(revnote)
		upw_pages[pagename] = (pagetext, revnote)
		x="/showpage/%s" % (quote_plus(pagename))
		raise cherrypy.HTTPRedirect(x)
	postpage.exposed=True

	def formshow(self, pagename):
		pagename = onlySafe(pagename)
		x="/showpage/%s" % (quote_plus(pagename))
		raise cherrypy.HTTPRedirect(x)
	formshow.exposed=True

	def showpage(self, *args):
		if not args:
			self.index()
		pagename = unquote_plus(onlySafe(args[0]))
		if not upw_pages.ispage(pagename):
			raise cherrypy.HTTPRedirect("/editpage/%s" % (quote_plus(pagename)))
		id = None
		if len(args) > 1:
			try:
				id = int(args[1])
			except ValueError:
				id = None
		x = upw_pages.get_item(pagename, id)
		if x == None:
			self.index() # FIXME -- should show bad index error
		(pagetext, id) = x 
		pagetext = ref_transform(pagetext)
		repl = {'<<PAGETEXT>>': pagetext, '<<TITLE>>': pagename, '<<QTITLE>>': quote_plus(pagename), '<<ID>>':id}
		pgparts= ['display_head', 'body_prefix', ('display_body', False), 'body_postfix', 'html_close']
		return buildpage(pgparts, repl)
	showpage.exposed=True

	def next(self, *args):
		if len(args)<2:
			self.index()
		pagename = unquote_plus(onlySafe(args[0]))
		if not upw_pages.ispage(pagename):
			raise cherrypy.HTTPRedirect("/editpage/%s" % (quote_plus(pagename)))
		try:
			id = int(args[1])
		except ValueError:
			self.index()
		x = upw_pages.get_next(pagename, id)
		if x == None:
			x = upw_pages.get_last(pagename) # Attempt to get past last page returns last valid page
		(pagetext, id) = x 
		pagetext = ref_transform(pagetext)
		repl = {'<<PAGETEXT>>': pagetext, '<<TITLE>>': pagename, '<<QTITLE>>': quote_plus(pagename), '<<ID>>':id}
		pgparts= ['display_head', 'body_prefix', ('display_body', False), 'body_postfix', 'html_close']
		return buildpage(pgparts, repl)
	next.exposed=True

	def previous(self, *args):
		if len(args)<2:
			self.index()
		pagename = unquote_plus(onlySafe(args[0]))
		if not upw_pages.ispage(pagename):
			raise cherrypy.HTTPRedirect("/editpage/%s" % (quote_plus(pagename)))
		try:
			id = int(args[1])
		except ValueError:
			self.index()
		x = upw_pages.get_previous(pagename, id)
		if x == None:
			x = upw_pages.get_first(pagename) # Attempt to get before first page returns first valid page
		(pagetext, id) = x 
		pagetext = ref_transform(pagetext)
		repl = {'<<PAGETEXT>>': pagetext, '<<TITLE>>': pagename, '<<QTITLE>>': quote_plus(pagename), '<<ID>>':id}
		pgparts= ['display_head', 'body_prefix', ('display_body', False), 'body_postfix', 'html_close']
		return buildpage(pgparts, repl)
	previous.exposed=True

	def showrevs(self, *args):
		if len(args)<1:
			self.index()
		pagename = unquote_plus(onlySafe(args[0]))
		if not upw_pages.ispage(pagename):
			self.index()
		x = upw_pages.get_revisions(pagename)
		if x == None:
			self.index()
		pg = []
		for (id, title, revnote) in x:
			titleq = quote_plus(title)
			title=html_escape(title)
			revnote = html_escape(revnote)
			pg.append("""<a href="/showpage/%s/%s">%s -- %s</a><br />\n""" % (titleq, id, title, revnote))
		pagetext = "".join(pg)
		repl = {'<<PAGETEXT>>': pagetext, '<<TITLE>>': pagename, '<<QTITLE>>': quote_plus(pagename), '<<ID>>':id}
		pgparts= ['display_head', 'body_prefix', ('display_body', False), 'body_postfix', 'html_close']
		return buildpage(pgparts, repl)
	showrevs.exposed=True

def buildpage(pgparts, repl):
	x = []
	for part in pgparts:
		if type(part) == TupleType:
			(part, q) = part
			x.append(macrepl(upw_strings[part], repl, quote=q))
		else:
			x.append(macrepl(upw_strings[part], repl))
	return "".join(x)


if __name__ == "__main__":
	# Initialize and test pysqlite database
	dbname='/home/jricher/Python_Code/upwiki.db'
	if not os.path.isfile(dbname):
		print "Warning: database not found - creating and populating database.....",
		db_init(dbname)
		print "done."
	upw_config = SQLHash(dbname,'config')
	upw_strings = SQLHash(dbname, 'strings')
	upw_pages = SQLPage(dbname)
	if not upw_pages.ispage('Home'):
		upw_pages['Home'] = "This is a home page.<br />It is a nice home page.<br />It is my home page.<br />I hope you like it.\n"

	cherrypy.root=WSRoot()
	cherrypy.config.update(file="myserver.conf")
	cherrypy.server.start() 
